﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using HotShot.Service.BusinessLogic;
using HotShot.Service.BusinessLogic.Worker;

namespace HotShot.Service
{
    partial class HotShotService : ServiceBase
    {
        internal GlobalCommunicationWorker gcp;
        internal LocalCommunicationWorker lcp;
        internal HealthCommunicationWorker hcp;
        internal CorrelationResultWorker crp;

        public HotShotService()
        {
            InitializeComponent();
        }

        public void Initialize()
        {
            ClusterProcessorLogic.Current.Initialize();
            QueueCommunicationLogic.Current.Initialize();

            gcp = new GlobalCommunicationWorker();
            lcp = new LocalCommunicationWorker();
            hcp = new HealthCommunicationWorker();
            crp = new CorrelationResultWorker();
            gcp.Initialize(".", "GCP", 10);
            lcp.Initialize(".", "LCP", 10);
            hcp.Initialize(".", "HCP", 60000);
            crp.Initialize(".", "CRP", 10);

            // Send initialize message to global input queue
            QueueCommunicationLogic.Current.SendInitMessage();

            // Start lcp to receive and process KnownNodes messages
            lcp.ExecuteAsync();
            DateTime startupTimeout = DateTime.Now.AddMilliseconds(Common.StartupDelayMs);
            while (ClusterProcessorLogic.Current.GetKnownNodes(false, false).Count == 0 && DateTime.Now < startupTimeout)
            {
                Thread.Sleep(100);
            }

            // By now, we should know about any existing nodes, if they are available. If there is none, we may safely assume that we're the first one alive.
            ClusterProcessorLogic.Current.CalculateHashKey();

            // Send first ping to broadcast hash key
            QueueCommunicationLogic.Current.Broadcast(Messages.Ping(null), null);

            // Start polling
            gcp.ExecuteAsync();
            hcp.ExecuteAsync();
            crp.ExecuteAsync();

        }

        public void TearDown()
        {
            gcp.ExecuteAsyncCancel();
            lcp.ExecuteAsyncCancel();
            hcp.ExecuteAsyncCancel();
            crp.ExecuteAsyncCancel();
        }

        protected override void OnStart(string[] args)
        {
            // TODO: Add code here to start your service.
        }

        protected override void OnStop()
        {
            // TODO: Add code here to perform any tear-down necessary to stop your service.
        }
    }
}
